import { Response } from 'express';
import { AuthenticatedRequest } from '../types/auth';
import { AIRecommendationService } from '../services/aiRecommendationService';
import { ApiError } from '../utils/ApiError';
import { StatusCodes } from '../constants/statusCodes';
import { logger } from '../utils/logger';
import { Role } from '@prisma/client';
import { z } from 'zod';

// 验证Schema
const recommendationRequestSchema = z.object({
  params: z.object({
    studentId: z.string().uuid('无效的学生ID')
  }),
  query: z.object({
    subject: z.string().min(1, '学科不能为空')
  })
});

const learningPathRequestSchema = z.object({
  params: z.object({
    studentId: z.string().uuid('无效的学生ID')
  }),
  body: z.object({
    subject: z.string().min(1, '学科不能为空'),
    targetTopic: z.string().min(1, '目标知识点不能为空')
  })
});

export const aiRecommendationController = {
  // 获取个性化学习建议
  async getPersonalizedRecommendations(req: AuthenticatedRequest, res: Response) {
    try {
      if (!req.user) {
        throw new ApiError(StatusCodes.UNAUTHORIZED, '未授权访问');
      }

      // 验证权限（必须是教师或管理员，或者是学生本人）
      const { studentId } = req.params;
      const { subject } = req.query;

      if (
        req.user.role !== Role.ADMIN &&
        req.user.role !== Role.TEACHER &&
        req.user.id !== studentId
      ) {
        throw new ApiError(StatusCodes.FORBIDDEN, '无权访问此学生的数据');
      }

      const validatedData = recommendationRequestSchema.parse({
        params: { studentId },
        query: { subject }
      });

      const recommendations = await AIRecommendationService.getPersonalizedRecommendations(
        validatedData.params.studentId,
        validatedData.query.subject
      );

      logger.info('获取个性化建议成功', {
        studentId,
        subject,
        requestedBy: req.user.id
      });

      res.json({
        success: true,
        data: recommendations
      });
    } catch (error) {
      logger.error('获取个性化建议失败', {
        context: 'aiRecommendationController.getPersonalizedRecommendations',
        error
      });
      throw error;
    }
  },

  // 获取学习路径建议
  async getLearningPathRecommendations(req: AuthenticatedRequest, res: Response) {
    try {
      if (!req.user) {
        throw new ApiError(StatusCodes.UNAUTHORIZED, '未授权访问');
      }

      const { studentId } = req.params;
      const { subject, targetTopic } = req.body;

      // 验证权限
      if (
        req.user.role !== Role.ADMIN &&
        req.user.role !== Role.TEACHER &&
        req.user.id !== studentId
      ) {
        throw new ApiError(StatusCodes.FORBIDDEN, '无权访问此学生的数据');
      }

      const validatedData = learningPathRequestSchema.parse({
        params: { studentId },
        body: { subject, targetTopic }
      });

      const recommendations = await AIRecommendationService.getLearningPathRecommendations(
        validatedData.params.studentId,
        validatedData.body.subject,
        validatedData.body.targetTopic
      );

      logger.info('获取学习路径建议成功', {
        studentId,
        subject,
        targetTopic,
        requestedBy: req.user.id
      });

      res.json({
        success: true,
        data: recommendations
      });
    } catch (error) {
      logger.error('获取学习路径建议失败', {
        context: 'aiRecommendationController.getLearningPathRecommendations',
        error
      });
      throw error;
    }
  },

  // 获取学生的所有建议历史
  async getRecommendationHistory(req: AuthenticatedRequest, res: Response) {
    try {
      if (!req.user) {
        throw new ApiError(StatusCodes.UNAUTHORIZED, '未授权访问');
      }

      const { studentId } = req.params;

      // 验证权限
      if (
        req.user.role !== Role.ADMIN &&
        req.user.role !== Role.TEACHER &&
        req.user.id !== studentId
      ) {
        throw new ApiError(StatusCodes.FORBIDDEN, '无权访问此学生的数据');
      }

      const history = await prisma.recommendationRecord.findMany({
        where: {
          studentId,
          status: 'ACTIVE'
        },
        orderBy: {
          createdAt: 'desc'
        }
      });

      res.json({
        success: true,
        data: history
      });
    } catch (error) {
      logger.error('获取建议历史失败', {
        context: 'aiRecommendationController.getRecommendationHistory',
        error
      });
      throw error;
    }
  }
};
